package com.demo.crm.springboot3security.service.impl;

import java.time.LocalDateTime;
import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.demo.crm.springboot3security.entity.FormField;
import com.demo.crm.springboot3security.entity.table.Tables;
import com.demo.crm.springboot3security.mapper.FormFieldMapper;
import com.demo.crm.springboot3security.service.FormFieldService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class FormFieldServiceImpl implements FormFieldService {
    private final FormFieldMapper formFieldMapper;

    @Override
    @Transactional
    public List<FormField> saveAll(List<FormField> fields) {
        fields.forEach(formFieldMapper::insert);
        return fields;
    }

    @Override
    public FormField save(FormField field) {
        formFieldMapper.insert(field);
        return field;
    }

    @Override
    public void delete(Long id) {
        formFieldMapper.deleteById(id);
    }

    @Override
    public FormField findById(Long id) {
        return formFieldMapper.selectOneById(id);
    }

    @Override
    public List<FormField> findByFormId(Long formId) {
        return formFieldMapper.selectListByQuery(QueryWrapper.create().where(Tables.FORM_FIELD.FORM_ID.eq(formId))
                .orderBy(Tables.FORM_FIELD.ORDER_NUM.asc()));
    }

    @Override
    public FormField findByNameAndFormId(String name, Long formId) {
        return formFieldMapper.selectOneByQuery(
                QueryWrapper.create().where(Tables.FORM_FIELD.NAME.eq(name)).and(Tables.FORM_FIELD.FORM_ID.eq(formId)));
    }

    @Override
    public List<FormField> findByFormIdOrderByDisplayOrder(Long formId) {
        return formFieldMapper.selectListByQuery(
                QueryWrapper.create().where(Tables.FORM_FIELD.FORM_ID.eq(formId))
                        .orderBy(Tables.FORM_FIELD.ORDER_NUM.asc()));
    }

    @Override
    public List<FormField> findAll() {
        return formFieldMapper.selectListByQuery(QueryWrapper.create().orderBy(Tables.FORM_FIELD.ORDER_NUM.asc()));
    }

    @Override
    public Page<FormField> findByPage(int pageNumber, int pageSize) {
        QueryWrapper queryWrapper = QueryWrapper.create().orderBy(Tables.FORM_FIELD.ORDER_NUM.asc());

        Page<FormField> page = new Page<>(pageNumber, pageSize);
        return formFieldMapper.paginate(page, queryWrapper);
    }

    @Override
    @Transactional
    public void updateDisplayOrder(Long fieldId, Integer displayOrder) {
        FormField field = findById(fieldId);
        if (field != null) {
            field.setOrderNum(displayOrder);
            field.setUpdatedAt(LocalDateTime.now());
            formFieldMapper.update(field);
        }
    }

    @Override
    @Transactional
    public void batchUpdateDisplayOrder(List<FormField> fields) {
        for (FormField field : fields) {
            updateDisplayOrder(field.getId(), field.getOrderNum());
        }
    }

    @Override
    public boolean existsByNameAndFormId(String name, Long formId) {
        return formFieldMapper.selectCountByQuery(QueryWrapper.create().where(Tables.FORM_FIELD.NAME.eq(name))
                .and(Tables.FORM_FIELD.FORM_ID.eq(formId))) > 0;
    }

    @Override
    @Transactional
    public void deleteByFormId(Long formId) {
        formFieldMapper.deleteByQuery(QueryWrapper.create().where(Tables.FORM_FIELD.FORM_ID.eq(formId)));
    }
}